/**
 * 
 */
package com.newture.lxz.util;

import org.apache.commons.beanutils.PropertyUtils;

import java.util.HashMap;
import java.util.Map;


/**
 * @author huxiao
 *
 */
public class  BeanKit {
	
	public interface ICallback {
		public void execute(Map<String, Object> tMap, String key, Object value);
	}

	/**
	 * 利用BeanUtils将Bean转换成Map，并过滤掉不需要的字段
	 * @param bean
	 * @return
	 */
	public static Map<String, Object> describe(Object bean, String[] keysRequired, ICallback callback) {
		Map<String, Object> tMap = new HashMap<String, Object>();
		Map<String, Object> propertyLog = null;
		
		try {
			propertyLog = PropertyUtils.describe(bean);
			for (Map.Entry<String, Object> entry : propertyLog.entrySet()) {
				String key = entry.getKey();
				String resetKey = resetKey(key);
				
				if(keysRequired == null) {
					/* 因为传入的参数一般是jfinal的model对象，里面存在dao
					 * 如果不指定key，则会把dao也put到map中去，引发不可预知的错误
					 * */
					throw new IllegalArgumentException("Keys must be designated");
				} 
				
				if(!ArrayKit.contains(keysRequired, resetKey)) {
					continue;
				}
				
				if(callback != null) {
					callback.execute(tMap, resetKey, entry.getValue());
				}

				tMap.put(resetKey, entry.getValue());
			}
		} catch (Exception e) {
			throw new IllegalStateException(e); 
		}
		
		return tMap;
	}
	
	/**
	 * 对map进行过滤并且对值进行转义
	 * @param map
	 * @param KeyNeeded
	 * @return
	 */
	public static Map<String, Object> describeMap(Map<String, Object> map, String[] KeyNeeded, ICallback callback) {
		Map<String, Object> tMap = new HashMap<String, Object>();
		try {
			for (Map.Entry<String, Object> entry : map.entrySet()) {
				String key = entry.getKey();
				String resetKey = resetKey(key);
				
				if(KeyNeeded != null) {
					if(!ArrayKit.contains(KeyNeeded, resetKey)) {
						continue;
					}
				} 
				
				if(callback != null) {
					callback.execute(tMap, resetKey, entry.getValue());
				}

				tMap.put(resetKey, entry.getValue());
			}
		} catch (Exception e) {
			throw new IllegalStateException(e);
		}
		
		return tMap;
	}

	/**
	 * userName ---> user_name
	 * @param key
	 * @return
	 */
	public static String resetKey(String key) {
		StringBuilder sb = new StringBuilder();
		char[] characters = key.toCharArray();
		String preChar = null;
		for(int i = 0; i < characters.length; i++) {
			char c = characters[i];
			
			if(Character.isDigit(c)) {
				if(preChar != null && !Character.isDigit(preChar.charAt(0))) {
					sb.append("_").append(c);
				} else {
					sb.append(c);
				}
			}
			else if(c != '_' && !Character.isLowerCase(c)) {
				sb.append("_").append(Character.toLowerCase(c));
			} 
			else {
				sb.append(c);
			}
			
			preChar = c + "";
		}
		return sb.toString();
	}

}
